include $(TOPDIR)/rules.mk
PKG_NAME:=frr
PKG_VERSION:=10.2.1
-PKG_RELEASE:=1
-PKG_SOURCE_DATE:=2025-01-21
+PKG_RELEASE:=2
+PKG_SOURCE_DATE:=2025-01-29
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
-PKG_SOURCE_VERSION:=989328c7e47c7bbcf3364d5424ac17f49fd05c57
+PKG_SOURCE_VERSION:=05f9d44340755e5ca612e4852b710f4037254e7b
PKG_SOURCE_URL:=https://codeload.github.com/FRRouting/frr/tar.gz/$(PKG_SOURCE_VERSION)?
-PKG_HASH:=d8ea2bad243cfcfd96b9b4a5dd524fe1deeb577cd535529babe24a02cae26f06
+PKG_HASH:=8873e1f638fc4457a30227181e3fd26414795e63dbb11911c2e669876589f228
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
pathd \
pbrd \
pimd \
+ pim6d \
ripd \
ripngd \
staticd \
$(INSTALL_BIN) ./files/frr $(1)/etc/init.d/
$(INSTALL_DIR) $(1)/usr/bin $(1)/etc/frr
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/vtysh $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/mgmtd $(1)/usr/sbin/
$(INSTALL_CONF) ./files/vtysh.conf $(1)/etc/frr/
$(INSTALL_DIR) $(1)/usr/lib $(1)/etc/frr
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfrr.so* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmgmt_be_nb.so* $(1)/usr/lib/
$(if $(CONFIG_FRR_SNMP),$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfrrsnmp.so* $(1)/usr/lib/,)
$(INSTALL_CONF) ./files/{frr.conf,daemons} $(1)/etc/frr/
endef
$(eval $(call BuildDaemon,pathd,))
$(eval $(call BuildDaemon,pbrd,))
$(eval $(call BuildDaemon,pimd,))
+$(eval $(call BuildDaemon,pim6d,))
$(eval $(call BuildDaemon,ripd,))
$(eval $(call BuildDaemon,ripngd,@IPV6))
$(eval $(call BuildDaemon,staticd,))
# - keep zebra first
# - watchfrr does NOT belong in this list
-DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pathd pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd"
+DAEMONS="zebra mgmtd bgpd ripd ripngd ospfd ospf6d isisd babeld pimd pim6d ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd pathd"
+
RELOAD_SCRIPT="$D_PATH/frr-reload.py"
#
# general helpers
#
+is_user_root () {
+# if [[ ! -z $FRR_NO_ROOT && "${FRR_NO_ROOT}" == "yes" ]]; then
+# return 0
+# fi
+
+ [ "${EUID:-$(id -u)}" -eq 0 ] || {
+ log_failure_msg "Only users having EUID=0 can start/stop daemons"
+ return 1
+ }
+}
debug() {
[ -n "$watchfrr_debug" ] || return 0
for daemon in $DAEMONS; do
eval cfg=\$$daemon
eval inst=\$${daemon}_instances
- [ "$daemon" = zebra -o "$daemon" = staticd ] && cfg=yes
+ [ "$daemon" = zebra -o "$daemon" = staticd -o "$daemon" = mgmtd ] && cfg=yes
if [ -n "$cfg" -a "$cfg" != "no" -a "$cfg" != "0" ]; then
if ! daemon_prep "$daemon" "$inst"; then
continue
fi
debug "$daemon enabled"
-# enabled="$enabled $daemon"
if [ -n "$inst" ]; then
debug "$daemon multi-instance $inst"
daemon_start() {
local dmninst daemon inst args instopt wrap bin
+
+ is_user_root || exit 1
+
+ all=false
+ [ "$1" = "--all" ] && { all=true; shift; }
+
daemon_inst "$1"
- ulimit -n $MAX_FDS > /dev/null 2> /dev/null
+ [ "$MAX_FDS" != "" ] && ulimit -n "$MAX_FDS" > /dev/null 2> /dev/null
daemon_prep "$daemon" "$inst" || return 1
if test ! -d "$V_PATH"; then
mkdir -p "$V_PATH"
instopt="${inst:+-n $inst}"
eval args="\$${daemon}_options"
- if eval "$all_wrap $wrap $bin $nsopt -d $frr_global_options $instopt $args"; then
+ cmd="$all_wrap $wrap $bin $nsopt -d $frr_global_options $instopt $args"
+ log_success_msg "Starting $daemon with command: '$cmd'"
+ if eval "$cmd"; then
log_success_msg "Started $dmninst"
- vtysh_b "$daemon"
+ if $all; then
+ debug "Skipping startup of vtysh until all have started"
+ else
+ vtysh_b "$daemon"
+ fi
else
log_failure_msg "Failed to start $dmninst!"
fi
local dmninst daemon inst pidfile vtyfile pid cnt fail
daemon_inst "$1"
+ is_user_root || exit 1
+
+ all=false
+ [ "$2" = "--reallyall" ] && all=true
+
pidfile="$V_PATH/$daemon${inst:+-$inst}.pid"
vtyfile="$V_PATH/$daemon${inst:+-$inst}.vty"
[ -r "$pidfile" ] || fail="pid file not found"
- [ -z "$fail" ] && pid="`cat \"$pidfile\"`"
+ $all && [ -n "$fail" ] && return 0
+ [ -z "$fail" ] && pid="$(cat "$pidfile")"
[ -z "$fail" -a -z "$pid" ] && fail="pid file is empty"
[ -n "$fail" ] || kill -0 "$pid" 2>/dev/null || fail="pid $pid not running"
if [ -n "$fail" ]; then
- log_failure_msg "Cannot stop $dmninst: $fail"
+ [ "$2" = "--quiet" ] || log_failure_msg "Cannot stop $dmninst: $fail"
return 1
fi
kill -2 "$pid"
cnt=1200
while kill -0 "$pid" 2>/dev/null; do
- sleep 1
+#
+# hack to have sub second delay and speed up the restart
+#
+ start=$(cut -d ' ' -f 1 /proc/uptime | awk '{print int($1 * 1000)}')
+ while :; do
+ now=$(cut -d ' ' -f 1 /proc/uptime | awk '{print int($1 * 1000)}')
+ elapsed=$((now - start))
+ if [ $elapsed -ge 100 ]; then # 100 milliseconds
+ break
+ fi
+ done
[ $(( cnt -= 1 )) -gt 0 ] || break
done
if kill -0 "$pid" 2>/dev/null; then
- log_failure_msg "Failed to stop $dmninst, pid $pid still running"
+ [ "$2" = "--quiet" ] || log_failure_msg "Failed to stop $dmninst, pid $pid still running"
still_running=1
return 1
else
- log_success_msg "Stopped $dmninst"
+ [ "$2" = "--quiet" ] || log_success_msg "Stopped $dmninst"
rm -f "$pidfile"
return 0
fi
pidfile="$V_PATH/$daemon${inst:+-$inst}.pid"
[ -r "$pidfile" ] || return 3
- pid="`cat \"$pidfile\"`"
+ pid="$(cat "$pidfile")"
[ -z "$pid" ] && return 1
kill -0 "$pid" 2>/dev/null || return 1
return 0
cmd="$1"
shift
- if [ "$1" = "all" -o -z "$1" ]; then
+ if [ "$1" = "all" ] || [ -z "$1" ]; then
case "$cmd" in
start) all_start;;
stop) all_stop;;
restart)
- all_stop
+ all_stop --quiet
all_start
;;
*) $cmd "$@";;